package com.ng.framework.view.desktop;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;

import javax.swing.DefaultListModel;
import javax.swing.JList;

public class NGList<T> extends JList {
	
	private static final long serialVersionUID = -2685899946523217729L;

	private Class<T> clazz;
	private DefaultListModel defaultListModel = new DefaultListModel();
	
	public NGList(Class<T> clazz) {
		super();
		
		this.init(clazz);
	}
	
	public NGList(Class<T> clazz, T[] listData) {
		super(listData);
		
		this.init(clazz);
	}
	
	public NGList(Class<T> clazz, Vector<T> listData) {
		super(listData);
		
		this.init(clazz);
	}
	
	private void init(Class<T> clazz) {
		this.clazz = clazz;
		
		this.setModel(defaultListModel);
	}
	
	public List<T> getElements() {
		List<T> elements = new ArrayList<T>();
		
		for(int i = 0; i < this.getModel().getSize(); i++) {
			elements.add(clazz.cast(defaultListModel.getElementAt(i)));
		}
		
		return elements;
	}
	
	public void addElements(List<T> elements) {
		this.addElements(elements, true);
	}
	
	public void addElements(List<T> elements, boolean sort) {
		if(sort) {
			List<T> allElements = new ArrayList<T>();
			List<T> currentElements = this.getElements();
			if(currentElements != null) {
				allElements.addAll(currentElements);
			}
			if(elements != null) {
				allElements.addAll(elements);
			}
			this.setElements(allElements, true);
		} else {
			for(T element : elements) {
				 this.addElement(element, false);
			}
		}
	}
	
	public void addElement(T element) {
		this.addElement(element, true);
	}
	
	public void addElement(T element, boolean sort) {
		if(sort) {
			List<T> allElements = this.getElements();
			if(element != null) {
				allElements.add(element);
			}
			this.setElements(allElements, true);
		} else {
			this.defaultListModel.addElement(element);
		}
	}
	
	public void setElements(List<T> elements, boolean sort) {
		this.removeAllElements();
		
		if(elements != null) {
			if(sort) {
				Collections.sort(elements, new Comparator<T>() {

					@Override
					public int compare(T o1, T o2) {
						return o1.toString().compareTo(o2.toString());
					}
				});
			}
			
			for(T element : elements) {
				this.addElement(element, false);
			}				
		}
	}
	
	public void removeElements(List<T> elements) {
		for(T element : elements) {
			this.removeElement(element);
		}
	}
	
	private void removeElement(T element) {
		this.defaultListModel.removeElement(element);
	}
	
	public List<T> getSelectedElements() {
		List<T> selectedElements = new ArrayList<T>();
		
		int[] selectedIndices = this.getSelectedIndices();
		for(int i : selectedIndices) {
			selectedElements.add(clazz.cast(defaultListModel.getElementAt(i)));
		}
		
		return selectedElements;
	}
	
	public void removeAllElements() {
		defaultListModel.removeAllElements();
	}
	
	public int getElementCount() {
		return defaultListModel.getSize();
	}

}
